package com.immediatus.engine.modifier;


import com.immediatus.engine.contracts.Interpolator;

public abstract class BaseSingleValueSpanModifier<T> extends BaseDurationModifier<T>{

	private final float _fromValue;
	private final float _valueSpan;

	public BaseSingleValueSpanModifier(final float duration_, final float fromValue_, final float toValue_) {
		this(duration_, fromValue_, toValue_, null, null);
	}

	public BaseSingleValueSpanModifier(final float duration_, final float fromValue_, final float toValue_, final Interpolator interpolator_) {
        this(duration_, fromValue_, toValue_, null, interpolator_);
	}

	public BaseSingleValueSpanModifier(final float duration_, final float fromValue_, final float toValue_, final IModifierListener<T> listener_) {
        this(duration_, fromValue_, toValue_, listener_, null);
	}

	public BaseSingleValueSpanModifier(final float duration_, final float fromValue_, final float toValue_, final IModifierListener<T> listener_, final Interpolator interpolator_) {
		super(duration_, listener_);
		this._fromValue = fromValue_;
		this._valueSpan = toValue_ - fromValue_;
	}

	protected BaseSingleValueSpanModifier(final BaseSingleValueSpanModifier<T> instance_) {
		super(instance_);
		this._fromValue = instance_._fromValue;
		this._valueSpan = instance_._valueSpan;
	}

	protected abstract void onSetInitialValue(final T item_, final float value_);
	protected abstract void onChangeValue(final T item_, final float secondsElapsed_, final float value_);

	@Override
	protected void onManagedInitialize(final T item_) {
		this.onSetInitialValue(item_, this._fromValue);
	}

	@Override
	protected void onManagedUpdate(final float secondsElapsed_, final T item_) {
        final float interpolation = getInterpolator().interpolate(secondsElapsed_ / getDuration());
        this.onChangeValue(item_, secondsElapsed_, this._fromValue + this._valueSpan * interpolation);
	}
}
